﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SCRUM.Core.BusinessObjects;
using System.Data.Common;

namespace SCRUM.Core.DataProviders
{
    /// <summary>
    /// Privider for comunication with the database
    /// </summary>
    public partial class DBDataProvider : DataProvider
	{
        /// <summary>
        /// Gets the tabs for specified user.
        /// </summary>
        /// <param name="user">The specified user.</param>
        public override IList<WidgetTab> GetTabs(User user)
        {
            IList<WidgetTab> tabs = new List<WidgetTab>();
            try
            {
                DbParameter userID = CreateParameter("userID", user.ID);

                connection.Open();
                DbDataReader data = GetVector("tab/GetTabs", userID);

                while (data.Read())
                {
                    WidgetTab tab = GetWidgetTab(data);
                    tabs.Add(tab);
                }
            }
            finally
            {
                connection.Close();
            }
            return tabs; 
        }

        /// <summary>
        /// Sets the tab active.
        /// </summary>
        /// <param name="tab">The tab to be set as active.</param>
        /// <param name="user">The user that is related.</param>
        public override void SetTabActive(WidgetTab tab, User user)
        {
            try
            {
                DbParameter tabID = CreateParameter("tabID", tab.ID);
                DbParameter userID = CreateParameter("userID", user.ID);

                connection.Open();
                ExecuteNonQueryTransaction("tab/SetActive", tabID, userID);               
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Gets the active tab.
        /// </summary>
        /// <param name="user">The logged user.</param>
        /// <returns>Active tab for logged user.</returns>
        public override WidgetTab GetActiveTab(User user)
        {
            WidgetTab tab = null;
            try
            {
                DbParameter userID = CreateParameter("userID", user.ID);

                connection.Open();
                DbDataReader data = GetVector("tab/GetActiveTab", userID);

                if (data.HasRows == false)//(!data.Read())
                {
                    connection.Close();
                    SetFirstTabActive(user);
                    return GetActiveTab(user);
                }
                else if (data.RecordsAffected > 1)
                {
                    throw new SCRUM.Core.Exceptions.Database.InconsistentDatabaseException("Active tab can be only one!");
                }
                else
                {
                    data.Read();
                    return tab = GetWidgetTab(data);
                }
            }
            finally
            {
                connection.Close();
            }
            //return tab; 
        }


        /// <summary>
        /// Sets the first tab active.
        /// </summary>
        /// <param name="user">The user.</param>
        private void SetFirstTabActive(User user)
        {
            WidgetTab tab;
            DbParameter dbuserID = CreateParameter("userID", user.ID);

            try
            {
                connection.Open();
                DbDataReader rtab = GetVector("tab/GetFirstUserTab", dbuserID);

                if (rtab.Read())
                {
                    tab = GetWidgetTab(rtab);
                }
                else
                {
                    tab = null;
                }
                //int status = ExecuteNonQuery("tab/SetFirstTabActive", dbuserID);

                //if (status != 1)
                //{
                //    throw new SCRUM.Core.Exceptions.Database.InconsistentDatabaseException("User has no tabs");
                //}
            }
            finally
            {
                connection.Close();
            }
            if (tab != null)
            {
                SetTabActive(tab, user);
            }
        }

        /// <summary>
        /// Gets the tab for the specified column.
        /// </summary>
        /// <param name="column">The column.</param>
        /// <returns>Tab that contains specified column.</returns>
        public override WidgetTab GetTab(WidgetColumn column)
        {
			WidgetTab tab = null;
			try
			{
                DbParameter columnID = CreateParameter("columnID", column.ID);

				connection.Open();
				DbDataReader data = GetVector("tab/GetTabForColumn", columnID);

				if (data.RecordsAffected > 1)
				{
					throw new SCRUM.Core.Exceptions.Database.InconsistentDatabaseException("Column can be only in one tab!");
				}

				if (data.Read())
				{
                    tab = GetWidgetTab(data);
				}
			}
			finally
			{
				connection.Close();
			}
			return tab; 
        }

        /// <summary>
        /// Creates the tab for specified user. Set this tab as active.
        /// </summary>
        /// <param name="tab">The tab.</param>
        /// <param name="user">The user.</param>
        /// <returns>newly created tab</returns>
        public override void CreateTab(string tabName, User user, int order)
        {
            try
            {
                DbParameter dbName = CreateParameter("name", tabName);
                DbParameter dbUserID = CreateParameter("userID", user.ID);
                DbParameter dbOrder = CreateParameter("order", order);

                connection.Open();
                //int projects = ExecuteNonQuery("tab/CreateTab", dbName, dbUserID, dbOrder);
                ExecuteNonQueryTransaction("tab/CreateTab", dbName, dbUserID, dbOrder);

            }
            finally
            {
                connection.Close();
            }
        }


        /// <summary>
        /// Deletes the tab for specified user
        /// </summary>
        /// <param name="tab"></param>
        /// <param name="user">The user.</param>
        public override void DeleteTab(WidgetTab tab)
        {
            try
            {
                DbParameter dbTabID = CreateParameter("tabID", tab.ID);
                connection.Open();
                ExecuteNonQueryTransaction("tab/DeleteTab", dbTabID);
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Fixes the order of tabs after deleting tab.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <param name="deletedTabID">The deleted tab ID.</param>
        public override void FixOrder(int userID, int deletedTabID)
        {
            DbParameter dbuserID = CreateParameter("userID", userID);
            DbParameter dbtabID = CreateParameter("tabID", deletedTabID);
            try
            {
                connection.Open();
                ExecuteNonQuery("tab/FixTabOrder", dbuserID, dbtabID);
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Renames the specified widget tab.
        /// </summary>
        /// <param name="widgetTab">The widget tab.</param>
        public override void Rename(WidgetTab widgetTab)
        {
            try
            {
                DbParameter dbTabID = CreateParameter("tabID",widgetTab.ID);
                DbParameter dbName = CreateParameter("name", widgetTab.Name);
                connection.Open();
                ExecuteNonQuery("tab/RenameTab", dbTabID, dbName);
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Gets the tabs for profile.
        /// </summary>
        /// <param name="userProfileID">The user profile ID.</param>
        /// <returns>Tabs to be copied</returns>
        public override IList<WidgetTab> GetTabsForProfile(int userProfileID)
        {
            DbParameter dbprofileID = CreateParameter("profileID", userProfileID);
            IList<WidgetTab> tabsToCopy = new List<WidgetTab>();
            try
            {
                connection.Open();

                DbDataReader tabs = GetGrid("tab/GetTabsForProfile", dbprofileID);

                while (tabs.Read())
                {
                    WidgetTab tab = GetWidgetTab(tabs);
                    tabsToCopy.Add(tab);
                }
            }
            finally
            {
                connection.Close();
            }
            return tabsToCopy;
        }

        /// <summary>
        /// Copies the tab for user.
        /// </summary>
        /// <param name="tab">The tab.</param>
        /// <param name="userID">The user ID.</param>
        /// <returns>Created tabID</returns>
        public override int CopyTabForUser(WidgetTab tab, int userID)
        {
            DbParameter dbname = CreateParameter("name", tab.Name);
            DbParameter dborder = CreateParameter("order", tab.Order);
            DbParameter dbactive = CreateParameter("active", 0);//tab.Active);
            DbParameter dbuserID = CreateParameter("userID", userID);

            try
            {
                connection.Open();

                ExecuteNonQuery("tab/CopyTabForUser", dbname, dborder, dbuserID, dbactive);
                return Convert.ToInt32(GetScalar("tab/GetLastInsertedTabID"));
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Gets the tab from DbDataReader
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns>Created Widget tab</returns>
        private WidgetTab GetWidgetTab(DbDataReader data)
        {
            int id = GetIntByColumn(data, "ID");
            string name= GetStringByColumn(data, "NAME");
              int us =  GetIntByColumn(data, "USER_ID");
                int or = GetIntByColumn(data, "ORDER");
               bool ac = GetBoolByColumn(data, "ACTIVE");
            return new WidgetTab(
                GetIntByColumn(data, "ID"),
                GetStringByColumn(data, "NAME"),
                GetIntByColumn(data, "USER_ID"),
                GetIntByColumn(data, "ORDER"),
                GetBoolByColumn(data, "ACTIVE"));
        }
    }
}
